#pragma once

#include <utility>

#include "HttpBase.h"

namespace network {

    class HttpRequest : public HttpBase {

    public:

        /**
          * @brief  构造一个空的Http请求
          * @note   该Http请求的方法默认为GET，版本默认为1.1，请求url为/
          */
        HttpRequest() : method_("GET"), url_("/") {}

        /**
          * @brief  按照请求方法和请求url构造一个空的Http请求
          * @param  method 请求方法
          * @param  url    请求url
          */
        HttpRequest(std::string method, std::string url) : method_(std::move(method)), url_(std::move(url)) {}

        /**
          * @brief  从字符串中解析Http请求
          * @note   如果解析原文不是Http格式会抛出std::runtime_error
          * @param  要解析的Http请求原始字符串
          * @retval 一个解析完成的Http请求对象
          */
        static HttpRequest parseRequest(const std::string &request);

        /**
          * @brief  将字符串解析为Http请求对象
          * @note   如果解析原文不是Http格式会抛出std::runtime_error
          * @param  request 要解析的Http请求原始字符串
          */
        void parse(const std::string &request);

        /**
          * @brief  设置请求URL
          * @param  要设置的URL字符串
          */
        void setUrl(const std::string &url) { url_ = url; }

        /**
          * @brief  获取请求URL
          * @retval url字符串
          */
        std::string getUrl() const;

        /**
          * @brief  设置请求方法
          * @param  要设置的请求方法
          */
        void setMethod(const std::string &method) { method_ = method; }

        /**
          * @brief  获取请求方法
          * @retval 请求方法
          */
        std::string getMethod() const { return method_; }

        /**
          * @brief  解析请求url中携带的参数
          * @note   暂不支持解析数组和对象结构参数
          * @retval 一个unordered_map<string,string>，key表示url请求参数中的键，value表示url请求参数中的值
          */
        std::unordered_map<std::string, std::string> getUrlParameter() const;

        /**
          * @brief  将Http请求类转化为字符串
          * @retval 一个字符串
          */
        std::string toString() const override;

    private:

        // 获取请求行
        void parseRequestLine(const std::string &line);

        // 获取一行请求头
        void parseHeaderLine(const std::string &header);

    private:

        // 请求方法
        std::string method_;

        // 请求URL
        std::string url_;

    };

}
